﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DatabaseKeyViewModel.cs" company="Marcin Jastrzebski">
//   Copyright (c) Marcin Jastrzebski (marcin@marcinj.net)
// </copyright>
// <summary>
//   Defines the DatabaseKeyViewModel type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace mPassRT.ViewModels.Key
{
    using System;
    using System.Windows.Input;

    using KeePassLib.Keys;

    using mPassRT.Common;
    using mPassRT.Utilities;

    using PopupLibrary;

    using Windows.Storage;
    using Windows.Storage.Pickers;

    /// <summary>The database key view model.</summary>
    public class DatabaseKeyViewModel : BindableBase
    {
        #region Fields

        /// <summary>The OK command.</summary>
        private readonly Command commitCommand;

        /// <summary>The commit button text.</summary>
        private string commitButtonText;

        /// <summary>The key file.</summary>
        private StorageFile keyFile;

        /// <summary>The password.</summary>
        private string password;

        /// <summary>The title.</summary>
        private string title;

        #endregion

        #region Constructors and Destructors

        /// <summary>Initializes a new instance of the <see cref="DatabaseKeyViewModel"/> class.</summary>
        public DatabaseKeyViewModel()
        {
            this.commitCommand = new Command
                                     {
                                         ExecuteHandler = this.OnOkCommandExecuted, 
                                         CanExecuteHandler = _ => this.IsKeyFileSet || this.IsPasswordSet
                                     };

#if DEBUG
            this.Password = "ThisIsMyPassword!";
#endif
        }

        #endregion

        #region Public Properties

        /// <summary>Gets the browse command.</summary>
        public ICommand BrowseCommand
        {
            get
            {
                return new Command { ExecuteHandler = this.OnBrowseCommandExecuted };
            }
        }

        /// <summary>Gets the cancel command.</summary>
        public ICommand CancelCommand
        {
            get
            {
                return new Command { ExecuteHandler = async _ => { await PopupManager.Current.CloseAsync(null); } };
            }
        }

        /// <summary>Gets or sets the commit button text.</summary>
        public string CommitButtonText
        {
            get
            {
                return this.commitButtonText;
            }

            set
            {
                this.SetProperty(ref this.commitButtonText, value);
            }
        }

        /// <summary>Gets the ok command.</summary>
        public ICommand CommitCommand
        {
            get
            {
                return this.commitCommand;
            }
        }

        /// <summary>Gets a value indicating whether is key file set.</summary>
        public bool IsKeyFileSet
        {
            get
            {
                return this.KeyFile != null;
            }
        }

        /// <summary>Gets a value indicating whether is password set.</summary>
        public bool IsPasswordSet
        {
            get
            {
                return string.IsNullOrEmpty(this.Password) == false;
            }
        }

        /// <summary>Gets or sets the key file.</summary>
        public StorageFile KeyFile
        {
            get
            {
                return this.keyFile;
            }

            set
            {
                this.SetProperty(ref this.keyFile, value);
                this.commitCommand.OnCanExecuteChanged();
            }
        }

        /// <summary>Gets or sets the password.</summary>
        public string Password
        {
            get
            {
                return this.password;
            }

            set
            {
                this.SetProperty(ref this.password, value);
                this.commitCommand.OnCanExecuteChanged();
            }
        }

        /// <summary>Gets or sets the title.</summary>
        public string Title
        {
            get
            {
                return this.title;
            }

            set
            {
                this.SetProperty(ref this.title, value);
            }
        }

        #endregion

        #region Methods

        /// <summary>Called when the browse command is executed to open the file picker.</summary>
        /// <param name="obj">The parameter is not used.</param>
        private async void OnBrowseCommandExecuted(object obj)
        {
            var picker = new FileOpenPicker { CommitButtonText = "Choose", ViewMode = PickerViewMode.List };
            picker.FileTypeFilter.Add(".png");
            picker.FileTypeFilter.Add(".gif");
            picker.FileTypeFilter.Add(".jpg");
            picker.FileTypeFilter.Add(".txt");
            picker.FileTypeFilter.Add(".csv");
            StorageFile file = await picker.PickSingleFileAsync();
            if (file != null)
            {
                this.KeyFile = file;
            }
        }

        /// <summary>The on ok command executed.</summary>
        /// <param name="parameter">The parameter.</param>
        private async void OnOkCommandExecuted(object parameter)
        {
            var key = new CompositeKey();

            // if password set, add it to the key
            if (this.IsPasswordSet)
            {
                key.AddUserKey(new KcpPassword(this.Password));
            }

            // if keyfile set, add it to the key
            if (this.IsKeyFileSet)
            {
                using (this.KeyFile.EnsurePathSafeToUse())
                {
                    key.AddUserKey(new KcpKeyFile(this.KeyFile.Path));
                }
            }

            // return the key
            await PopupManager.Current.CloseAsync(key);
        }

        #endregion
    }
}